/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cc.altius.dao.impl;

import cc.altius.dao.TicketDao;
import cc.altius.domain.CustomUserDetails;
import cc.altius.model.*;
import cc.altius.utils.DateUtils;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import javax.sql.DataSource;
import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

/**
 *
 * @author mudassar
 */
@Repository
public class TicketDaoImpl implements TicketDao {

    private SessionFactory sessionFactory;
    private HibernateTemplate hibernateTemplate;
    private DataSource dataSource;
    private JdbcTemplate jdbcTemplate;
    private Session session;
    private Query query;

    @Autowired
    public void setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
        this.jdbcTemplate = new JdbcTemplate(dataSource);
    }

    @Autowired
    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
        this.hibernateTemplate = new HibernateTemplate(sessionFactory);
    }

    @Override
    @Transactional
    public int addTicket(Ticket ticket, String followupDate, int hospitalId, int appSpecialistId) {
        try {
            session = this.sessionFactory.getCurrentSession();
            int curUser = ((CustomUserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getUserId();
            Date curDate = DateUtils.getCurrentDateObject(DateUtils.IST);
            ticket.setLastModifiedBy(new User(curUser));
            ticket.setLastModifiedDate(curDate);
            ticket.setCreatedDate(curDate);
            ticket.setCreatedBy(new User(curUser));
            if (ticket.getAssignedTo() != null) {
                ticket.setAssignedTo(new User(ticket.getAssignedTo().getUserId()));
            } else {
                ticket.setAssignedTo(new User(curUser));
            }
            if (hospitalId != 0) {
                ticket.setHospital(new Hospital(hospitalId));
            } else {
                ticket.setHospital(null);
            }
            if (appSpecialistId != 0) {
                ticket.setAppSpecialist(new AppSpecialist(appSpecialistId));
            } else {
                ticket.setAppSpecialist(null);
            }
            ticket.setDoctor(ticket.getDoctor());
            ticket.setAssignedTo(new User(curUser));
            //String status = "Open";
            ticket.setStatus(ticket.getStatus());
            if (!followupDate.isEmpty()) {
                DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm");
                Date followupDate1 = (Date) dateFormat.parse(followupDate);

                ticket.setFollowupDate(followupDate1);
            } else {
                ticket.setFollowupDate(null);
            }

            TransTicket transTicket = new TransTicket();
            transTicket.setLastModifiedBy(new User(curUser));
            transTicket.setLastModifiedDate(curDate);
            transTicket.setNotes(ticket.getNotes());
            transTicket.setCallType(ticket.getCallType());
            transTicket.setDisposition(ticket.getDisposition());
            transTicket.setCheifComplaint(ticket.getCheifComplaint());
            transTicket.setStatus(ticket.getStatus());
            transTicket.setRecordingId(ticket.getRecordingId());
            if (!followupDate.isEmpty()) {
                transTicket.setFollowupDate(ticket.getFollowupDate());
            } else {
                transTicket.setFollowupDate(null);
            }
            if (ticket.getAssignedTo() != null) {
                transTicket.setAssignedTo(new User(ticket.getAssignedTo().getUserId()));
            } else {
                transTicket.setAssignedTo(new User(curUser));
            }
            transTicket.setAssignedTo(new User(curUser));
            if (hospitalId != 0) {
                transTicket.setHospital(ticket.getHospital());
            } else {
                transTicket.setHospital(null);
            }
            if (appSpecialistId != 0) {
                transTicket.setAppSpecialist(ticket.getAppSpecialist());
            } else {
                transTicket.setAppSpecialist(null);
            }

            if (ticket.getDoctor().getDoctorId() == 0) {
                ticket.setDoctor(null);
                transTicket.setDoctor(null);
            } else {
                transTicket.setDoctor(ticket.getDoctor());
            }
            int ticketId = (Integer) this.hibernateTemplate.save(ticket);
            transTicket.setTicket(ticket);
            hibernateTemplate.save(transTicket);
            return ticketId;
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

    @Override
    @Transactional
    public List<Ticket> getOpenTicketList(int customerId) {
        int curUser = ((CustomUserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getUserId();
        session = this.sessionFactory.getCurrentSession();
        Criteria cr = session.createCriteria(Ticket.class);
        cr.add(Restrictions.eq("customer.customerId", customerId));
        cr.add(Restrictions.eq("status", "Open"));
        //cr.add(Restrictions.eq("assignedTo.userId", curUser));
        cr.addOrder(Order.desc("lastModifiedDate"));
        List<Ticket> tickets = cr.list();
        return tickets;
    }

    @Override
    @Transactional
    public List<Ticket> getClosedTicketList(int customerId) {
        int curUser = ((CustomUserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getUserId();
        session = this.sessionFactory.getCurrentSession();
        Criteria cr = session.createCriteria(Ticket.class);
        cr.add(Restrictions.eq("customer.customerId", customerId));
        cr.add(Restrictions.eq("status", "Closed"));
        //cr.add(Restrictions.eq("assignedTo.userId", curUser));
        cr.addOrder(Order.desc("lastModifiedDate"));
        List<Ticket> tickets = cr.list();
        return tickets;
    }

    @Override
    @Transactional
    public Ticket getTicketByTicketId(int ticketId) {
        Session session = this.sessionFactory.getCurrentSession();
        Query query = session.createQuery("from Ticket t where t.ticketId=" + ticketId);
        return (Ticket) query.uniqueResult();
    }

    @Override
    @Transactional
    public void updateTicket(Ticket ticket, String followupDate, int hospitalId, int appSpecialistId) {
        session = this.sessionFactory.getCurrentSession();
        try {
            int curUser = ((CustomUserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getUserId();
            Date curDate = DateUtils.getCurrentDateObject(DateUtils.IST);
            //int userId = ticket.getAssignedTo().getUserId();
            String hql = "Update "
                    + " Ticket t set"
                    + " lastModifiedDate=:lastModifiedDate, "
                    + " lastModifiedBy.userId=:lastModifiedBy,"
                    + " notes=:notes, "
                    + " callType.callTypeId=:callTypeId,"
                    + " disposition.dispositionId=:dispositionId,"
                    + " cheifComplaint=:cheifComplaint,"
                    + " followupDate=:followupDate, "
                    + " status=:status, "
                    + " doctor.doctorId=:doctorId,"
                    + " hospital.hospitalId=:hospitalId,"
                    + " appSpecialist.appSpecialistId=:appSpecialistId, "
                    + " ticketDesc=:ticketDesc, "
                    + " recordingId=:recordingId,"
                    + " assignedTo.userId=:userId1"
                    + " WHERE ticketId=:ticketId";
            query = session.createQuery(hql);
            query.setParameter("lastModifiedDate", curDate);
            query.setParameter("lastModifiedBy", curUser);
            query.setParameter("notes", ticket.getNotes());
            query.setParameter("callTypeId", ticket.getCallType().getCallTypeId());
            query.setParameter("dispositionId", ticket.getDisposition().getDispositionId());
            query.setParameter("cheifComplaint", ticket.getCheifComplaint());
            if (!followupDate.isEmpty()) {
                DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm");
                Date followupDate1 = (Date) dateFormat.parse(followupDate);
                query.setParameter("followupDate", followupDate1);
            } else {
                query.setParameter("followupDate", null);
            }
            query.setParameter("status", ticket.getStatus());
            query.setParameter("doctorId", ticket.getDoctor().getDoctorId());
            if (hospitalId != 0) {
                query.setParameter("hospitalId", hospitalId);
            } else {
                query.setParameter("hospitalId", null);
            }
            if (appSpecialistId != 0) {
                query.setParameter("appSpecialistId", appSpecialistId);
            } else {
                query.setParameter("appSpecialistId", null);
            }
            query.setParameter("ticketDesc", ticket.getTicketDesc());
            query.setParameter("recordingId", ticket.getRecordingId());
            if (ticket.getAssignedTo() != null && ticket.getAssignedTo().getUserId() != 0) {
                System.out.println("Assigned to userId :" + ticket.getAssignedTo().getUserId());
                System.out.println("inside not null");
                query.setParameter("userId1", ticket.getAssignedTo().getUserId());
            } else {
                System.out.println("null value  curUser: " + curUser);
                query.setParameter("userId1", curUser);
            }
            query.setParameter("ticketId", ticket.getTicketId());

            TransTicket transTicket = new TransTicket();
            transTicket.setTicket(ticket);
            transTicket.setLastModifiedDate(curDate);
            transTicket.setLastModifiedBy(new User(curUser));
            transTicket.setNotes(ticket.getNotes());
            transTicket.setCallType(ticket.getCallType());
            transTicket.setDisposition(ticket.getDisposition());
            transTicket.setCheifComplaint(ticket.getCheifComplaint());
            transTicket.setStatus(ticket.getStatus());
            transTicket.setRecordingId(ticket.getRecordingId());
            if (ticket.getAssignedTo() != null && ticket.getAssignedTo().getUserId() != 0) {
                transTicket.setAssignedTo(new User(ticket.getAssignedTo().getUserId()));
            } else {
                transTicket.setAssignedTo(new User(curUser));
            }
            if (!followupDate.isEmpty()) {
                DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm");
                Date followupDate1 = (Date) dateFormat.parse(followupDate);
                transTicket.setFollowupDate(followupDate1);
            } else {
                transTicket.setFollowupDate(null);
            }

            if (hospitalId != 0) {
                transTicket.setHospital(new Hospital(hospitalId));
            } else {
                transTicket.setHospital(null);
            }
            if (appSpecialistId != 0) {
                transTicket.setAppSpecialist(new AppSpecialist(appSpecialistId));
            } else {
                transTicket.setAppSpecialist(null);
            }
            if (ticket.getDoctor().getDoctorId() == 0) {
                System.out.println("if (customer.getDoctor().getDoctorId() == 0)");
                ticket.setDoctor(null);
                query.setParameter("doctorId", null);
                transTicket.setDoctor(null);
            } else {
                query.setParameter("doctorId", ticket.getDoctor().getDoctorId());
                transTicket.setDoctor(ticket.getDoctor());
            }
            query.executeUpdate();
            session.save(transTicket);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    @Transactional
    public List<TransTicket> getTicketTransDetails(int ticketId) {
        List<TransTicket> l = null;

        try {
            l = this.hibernateTemplate.find(" select t FROM TransTicket t WHERE t.ticket.ticketId=" + ticketId + " ORDER BY t.lastModifiedDate DESC");
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        if (l.isEmpty()) {
            return null;
        } else {
            return l;
        }
    }

    @Override
    @Transactional
    public List<Map<String, Object>> getFollowupListForTicket(int dispositionId, int userId, String startDate, String stopDate,int paymentTypeId) {
        CustomUserDetails curUserObj = (CustomUserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        System.out.println("curUserObj :" + curUserObj.getBusinessFunction());
        System.out.println("inside folloeuonkscjnskd");
        session = this.sessionFactory.getCurrentSession();
        //String status="Open";
        System.out.println("startDate :" + startDate);
        System.out.println("stopDate :" + stopDate);
        String s = " SELECT new map(t.ticketId as ticketId ,"
                + " pt.paymentTypeName as paymentTypeName  ,"
                + " t.status as status,"
                + " c.customerId as customerId,"
                + " c.customerName as customerName, "
                + " c.empId as empId,"
                + " c.mrNo as mrNo,"
                + " c.phone1 as phone1,"
                + " ct.callTypeName as callTypeName,"
                + " t.followupDate as followupDate,"
                + " c.important as important,"
                + " t.lastModifiedDate as lastModifiedDate,"
                + " c.registrationStatus as registrationStatus,"
                + " d.dispositionId as dispositionId,"
                + " assignedTo.username as assignedTo1,"
                + " user.username as createdBy,"
                + " d.dispositionName as dispositionName)"
                + " from Ticket t"
                + " left join t.customer c"
                + " left join c.paymentTypeId pt"
                + " left join t.disposition d "
                + " left join t.lastModifiedBy user "
                + " left join t.callType ct "
                + " left join t.assignedTo assignedTo"
                + " WHERE t.followupDate is not null and t.followupDate>='" + startDate + " 00:00:00' and t.followupDate<='" + stopDate + " 23:59:59'  and t.status = 'Open' ";
        if (userId == 0) {
            SimpleGrantedAuthority authority = new SimpleGrantedAuthority("ROLE_BF_SHOW_ALL_FOLLOWUP_LIST");
            if (curUserObj.getBusinessFunction().contains(authority)) {
            } else {
                s += " and assignedTo.userId=" + curUserObj.getUserId() + " ";
            }
        } else {
            s += " and assignedTo.userId=" + userId + " ";
        }

        if (dispositionId != 0) {
            s += " and d.dispositionId=" + dispositionId + " ";
        }
        
        if (paymentTypeId != 0) {
            s += " and pt.paymentTypeId=" + paymentTypeId + " ";
        }
        
        s += "  ORDER by t.followupDate ASC";
        
        query = session.createQuery(s);
        List<Map<String, Object>> tmpCustomerList = query.list();
        return tmpCustomerList;
    }

    @Override
    public List<PaymentType> getPaymentTypeList() {
        return this.hibernateTemplate.find("From PaymentType");
    }
}
